import React, { Component } from 'react';
import { graphql, compose } from 'react-apollo';
import gql from 'graphql-tag';
import { View, StyleSheet, Alert, TouchableOpacity, ScrollView, Text, Vibration } from 'react-native';
import { Icon, List, ListItem, Button, SideMenu, SearchBar } from 'react-native-elements';
import Loader from './widgets/Loader';
import RefreshScrollView from './widgets/RefreshScrollView';
import AssignFactoryButton from './components/AssignFactoryButton';
import { executor, primaryColor, toast } from './utils';
import { Calendar } from 'react-native-calendars';
import { BagCheckQuery } from './graphql';
import moment from 'moment';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white'
  },
  button: {
    paddingTop: 32
  },
  bagNotFound: {
    color: 'red'
  },
  list: {
    marginTop: 0
  },
  row: {
    flexDirection: 'row',
    alignItems: 'center'
  },
  header: {
    padding: 8
  },
  checked: {
    color: '#4CAF50'
  },
  selected: {
    color: primaryColor
  },
  orderNumber: {
    color: '#795548'
  },
  iconLeft: {
    marginLeft: 16
  },
  preview: {
    height: 50
  },
  express: {
    color: '#4CAF50'
  },
  premium: {
    color: '#FF5722'
  },
  business: {
    color: '#2196F3'
  },
  ready: {
    backgroundColor: '#C8E6C9'
  },
  icon: {
    marginRight: 16,
    color: primaryColor,
    fontSize: 16
  },
  iconLeft: {
    marginLeft: 16,
    color: primaryColor,
    fontSize: 16
  }
});

function getDefaultDate() {
  return moment([moment().year(), moment().month(), moment().date()]).subtract(1,'days').toDate().toString();
}

class BagCheckPage extends Component {
  static navigationOptions = ({navigation, screenProps}) => {
    return {
      title: `${(navigation.state.params&&navigation.state.params.selectWorker)||'All'}`,
      tabBarLabel: screenProps.chinese?`包检查`:`Bag Check`,
      tabBarIcon: ({tintColor}) => <Icon name='price-tag' type='entypo' color={tintColor} size={24}/>,
      headerLeft: (
        <TouchableOpacity onPress={() => navigation.navigate('AssignFactory')}>
          <Text style={styles.iconLeft}>{screenProps.chinese?'工厂':'Factories'}</Text>
        </TouchableOpacity>
      ),
      headerRight: (
        <TouchableOpacity onPress={() => {
          const { selects, date, checkingOrders } = navigation.state.params||{};
          const orderNumbers = selects&&checkingOrders&&checkingOrders.filter(order =>
            order.bags&&order.bags.find(bag=>selects.indexOf(bag)>=0)).map(order => order.orderNumber);

          navigation.navigate('FactoryAssign', {date, orderNumbers, onFinished: () => {
            navigation.setParams({selects:[]});
          }});
        }}>
          <Text style={styles.icon}>{screenProps.chinese?'分厂':'Assign'}</Text>
        </TouchableOpacity>
      )
    };
  }
  state = {}
  componentDidmount() {
    if (this.props.checkingOrders) {
      this.setState({checkingOrders: this.props.checkingOrders});
      this.props.navigation.setParams({checkingOrders:this.props.checkingOrders});
    }
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.checkingOrders!==this.props.checkingOrders) {
      this.setState({checkingOrders: nextProps.checkingOrders}); 
      nextProps.navigation.setParams({checkingOrders:nextProps.checkingOrders});
    }
  }
  onSelectDate = ({year, month, day, hour=0}, calendarOpen=false) => {
    const date = moment([year, month-1, day, hour]).toDate().toString();
    this.props.navigation.setParams({date});
    this.setState({isOpen: false});
  }
  onSelectBag = (bags) => {
    let selects = (this.props.navigation.state.params&&this.props.navigation.state.params.selects)||[];
    const select = bags.find(bag=>selects.indexOf(bag)>=0);
    if (select) {
      this.props.navigation.setParams({selects: selects.filter(select=>bags.indexOf(select)<0)});
    } else {
      selects = [...selects, ...bags];
      this.props.navigation.setParams({selects: selects.filter((bag, index)=>selects.indexOf(bag)===index)});
    }
  }
  onSideMenuChange = (isOpen) => this.setState({isOpen})
  onOpenMenu = () => this.setState({isOpen: true})
  onSelectWorker = (selectWorker) => {
    this.setState({isOpen: false});
    this.props.navigation.setParams({selectWorker});
  }
  handleBarCodeRead = (data) => {
    const selects = (this.props.navigation.state.params&&this.props.navigation.state.params.selects)||[];

    if (data&&data.length===4) {
      const bagNumber = `KK${data}`;
      if (selects.indexOf(bagNumber)>=0) {
        Alert.alert(
          `Bag ${bagNumber} already selected`,
          null,
          [
            {text: 'ok'},
          ],
          { cancelable: true }
        );
      } else {
        const checkingOrders = this.state.checkingOrders;
        const foundIndex = checkingOrders&&checkingOrders.findIndex(order=>order.bags&&order.bags.indexOf(bagNumber)>=0);
        if (foundIndex>=0) {
          Vibration.vibrate();
          this.setState({checkingOrders: [checkingOrders[foundIndex], ...checkingOrders.slice(0, foundIndex), ...checkingOrders.slice(foundIndex+1)]});
          this.props.navigation.setParams({selects: [...selects, bagNumber]});
        } else {
          executor(this.props.loadOrder, bagNumber)
            .then(({res}) => {
              if (res) {
                Alert.alert(
                  `[NOT FOUND] Bag ${bagNumber} is belong to #${res.loadOrder.displayId} picked up by ${res.loadOrder.pickup.workerName}`,
                  null,
                  [
                    {text: 'ok'},
                  ],
                  { cancelable: true }
                );
              } else {
                Alert.alert(
                  `Bag ${bagNumber} not found`,
                  null,
                  [
                    {text: 'ok'},
                  ],
                  { cancelable: true }
                );
              }
            });

          toast(`Not found locally, Loading...`);
        }
      }

      this.setState({inputNumner:null});
    } else {
      this.setState({inputNumner:data});
    }
  }
  onCheckBag = () => {
    const { selects } = this.props.navigation.state.params||{};
    if (!selects||selects.length===0) return toast('Please select bags');

    Alert.alert(
      `Received Confirm`,
      selects.join(', '),
      [
        {text: 'Cancel'},
        {text: 'Received', onPress: () => {
          executor(this.props.checkLaundryBags)
            .then(({res}) => {
              if (res) {
                toast('Bags checked');
                this.props.navigation.setParams({selects:[]});
              }
            });
          toast('Checking...');
        }}
      ],
      { cancelable: true }
    );
  }
  render() {
    let { checkingOrders } = this.state;
    let { loading, refetch, navigation } = this.props;
    const { selects, date, selectWorker } = navigation.state.params||{};
    const selectDate = date?moment(date):moment().subtract(1,'days');

    const workers = checkingOrders&&checkingOrders.filter(bag=>bag.pickupWorker).map(bag=>bag.pickupWorker);
    if (checkingOrders&&selectWorker) {
      checkingOrders = checkingOrders.filter(bag=>bag.pickupWorker===selectWorker);
    }

    let allUnchecked = 0;
    checkingOrders&&checkingOrders.map(order => {
      if (order.bags&&!order.ready) {
        allUnchecked += order.bags.length;
      }
    });

    return (
      <SideMenu isOpen={this.state.isOpen} onChange={this.onSideMenuChange}
        menu={
          <ScrollView>
            <Calendar hideExtraDays selected={[selectDate.format('YYYY-MM-DD')]} theme={{
              selectedDayBackgroundColor: primaryColor,
              todayTextColor: primaryColor,
              dotColor: primaryColor,
              arrowColor: primaryColor,}}
              onDayPress={this.onSelectDate} displayLoadingIndicator={loading}/>
              <Text style={styles.header}>Filter By Pickup Driver</Text>
              <List containerStyle={styles.list}>
                <ListItem title='All' rightIcon={{name:!selectWorker?'radio-button-checked':'radio-button-unchecked',color:!selectWorker?primaryColor:undefined}}
                  onPress={()=>this.onSelectWorker(null)}/>
                {workers&&workers.filter((worker, index)=>workers.indexOf(worker)===index)
                  .map((worker, index) => {
                    const select = selectWorker&&selectWorker===worker;
                    return <ListItem key={index} title={worker} rightIcon={{name:select?'radio-button-checked':'radio-button-unchecked',color:select?primaryColor:undefined}}
                      onPress={()=>this.onSelectWorker(worker)}/>;
                  })}
              </List>
          </ScrollView>
        }>
        <View style={styles.container}>
          <View style={styles.row}>
            <Button title={selectDate.format('Do')} backgroundColor='transparent' color={primaryColor}
              onPress={this.onOpenMenu}/>
            <View style={styles.container}>
              <SearchBar lightTheme keyboardType='numeric' value={this.state.inputNumner}
                onChangeText={this.handleBarCodeRead} inputStyle={{height:50}} placeholder='KK...'/>
            </View>
            <Button title={allUnchecked?`Receive ${selects?selects.length:0} / ${allUnchecked}`:'All Checked'}
              backgroundColor='transparent' color={allUnchecked?primaryColor:'#4CAF50'} onPress={this.onCheckBag}/>
          </View>
          {loading?<Loader/>:
            <RefreshScrollView refetch={refetch}>
              <List containerStyle={styles.list}>
                {checkingOrders&&checkingOrders.map(({orderId, orderStatus, orderNumber, bags, checkedBags, pickupWorker, ready, express, business, premium, assignedFactory, estDate}, index) => {
                  const select = bags&&selects&&bags.find(bag=>selects.indexOf(bag)>=0);

                  return <ListItem key={index} title={<Text>{express?<Text style={styles.express}>[Express]</Text>:''}{premium?<Text style={styles.premium}>[PREMIUM]</Text>:''}{business?<Text style={styles.business}>[BUSINESS]</Text>:''}<Text style={styles.orderNumber}>{`#${orderNumber}:`}</Text> {bags?bags.map(bag=><Text style={(checkedBags&&checkedBags.indexOf(bag)>=0)?styles.checked:((selects&&selects.indexOf(bag)>=0)?styles.selected:undefined)}>{`${bag}; `}</Text>):<Text style={styles.bagNotFound}>BAG MISSING</Text>}{estDate?` ${estDate}`:''}</Text>}
                    subtitle={`${orderStatus} <${pickupWorker||'n/a'}>${assignedFactory?`\r\nFactory: ${assignedFactory}`:''}`} subtitleNumberOfLines={2}
                    leftIcon={bags?{name:select?'check-box':'check-box-outline-blank',color:select?primaryColor:undefined}:undefined}
                    rightIcon={{name:'edit'}} onPress={() => bags&&this.onSelectBag(bags)} containerStyle={checkedBags?styles.ready:undefined}
                    onPressRightIcon={()=>this.props.navigation.navigate('BagScan', {date, input: true, update: true, id: orderId, laundryBags: bags, displayId:orderNumber})}/>;
                })}
              </List>
            </RefreshScrollView>
          }
        </View>
      </SideMenu>
    );
  }
}

export default compose(
  graphql(BagCheckQuery, {
    options: ({navigation:{state:{params}}}) => {
      return {
        variables: {
          date: (params&&params.date)||getDefaultDate()
        }
      };
    },
    props: ({data:{checkingOrders, refetch, loading}}) => {
      return {
        checkingOrders,
        loading,
        refetch
      };
    }
  }),
  graphql(gql`
    mutation checkLaundryBags($laundryBags:[String]!) {
      checkLaundryBags(laundryBags:$laundryBags)
    }
  `, {
    name: 'checkLaundryBags',
    props: ({ownProps:{navigation:{state:{params}}}, checkLaundryBags}) => {
      return {
        checkLaundryBags: () => checkLaundryBags({
          variables: {
            laundryBags: params&&params.selects
          },
          refetchQueries: [{
            query: BagCheckQuery,
            variables: { 
              date: (params&&params.date)||moment([moment().year(), moment().month(), moment().date()]).subtract(1,'days').toDate().toString()
            },
          }]
        })
      };
    }
  }),
  graphql(gql`
    mutation loadOrder($idOrBag:String!) {
      loadOrder(idOrBag:$idOrBag) {
        id
        displayId
        pickup {
          workerName
        }
      }
    }
  `, {
    name: 'loadOrder',
    props: ({loadOrder}) => {
      return {
        loadOrder: (idOrBag) => loadOrder({variables:{idOrBag}})
      };
    }
  })
)(BagCheckPage);


